<?php

declare (strict_types=1);

namespace app\store\model\customer;


use app\store\model\store\User;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * Class Service
 * @package app\store\model\customer
 */
class Service extends \app\common\model\customer\Service
{
    /**
     * 检索查询条件
     * @param array $param
     * @return array
     */
    private function getFilter(array $param = []): array
    {
        // 默认查询条件
        $param = $this->setQueryDefaultValue($param, [
            'search' => '',
            'month_type' => -1,
            'store_user_id' => '',
            'customer_id' => '',
            'customer_type' => -1,
            'package_status' => -1,
            'create_time' => []
        ]);
        // 检索查询条件
        $filter = [
            ['a.is_delete', '=', 0]
        ];
        if ($param['month_type'] == 1) {
            $filter[] = ['a.month', '>', 0];
        } elseif ($param['month_type'] == 2) {
            $filter[] = ['a.month', '=', 0];
        }
        !empty($param['customer_id']) && $filter[] = ['a.customer_id', '=', $param['customer_id']];
        $param['customer_type'] > -1 && $filter[] = ['c.customer_type', '=', $param['customer_type']];
        $param['package_status'] > -1 && $filter[] = ['b.status', '=', $param['package_status']];
        !empty($param['search']) && $filter[] = ['a.service_name', 'like', "%{$param['search']}%"];

        if (!empty($param['create_time'])) {
            $times = between_time($param['create_time']);
            $filter[] = ['a.create_time', '>=', $times['start_time']];
            $filter[] = ['a.create_time', '<', $times['end_time'] + 86400];
        }
        return $filter;
    }

    /**
     * 获取列表记录
     * @param array $param
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getList(array $param = [], array $store = [])
    {
        // 检索查询条件
        $filter = $this->getFilter($param);
        if (!empty($param['store_user_id']) && !empty($param['year_month'])) {
            $year_month = strtotime(trim($param['year_month'], '&quot;'));
            $currTime = strtotime(date('Y-m', $year_month) . date('-d H:i:s'));
            $firstDay = date('Y-m-01', $year_month);
            $lastDay = strtotime("$firstDay +1 month -1 day");
            $lastDay = strtotime(date("Y-m-d 23:59:59", $lastDay));
            $user = User::detail($param['store_user_id']);
            if ($user) {
                if ($user->position == 0) {
                    $package_ids = (new Package())->where(['store_user_id' => $user->store_user_id, 'status' => 2, 'is_delete' => 0])->column('package_id');
                    //收款金额*%
                    $where1 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.sales_commission_type', '=', 0],
                    ];
                    //固定金额
                    $where2 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.sales_commission_type', '=', 1],
                    ];
                    //每月提成
                    $where3 = [
                        ['a.start_time', '<=', $currTime],
                        ['a.end_time', '>=', $currTime],
                        ['a.package_id', 'in', $package_ids],
                        ['a.sales_commission_type', '=', 2],
                    ];
                } elseif ($user->position == 1) {
                    $package_ids = (new Package())->where(['kj_user_id' => $user->store_user_id, 'status' => 2, 'is_delete' => 0])->column('package_id');
                    //收款金额*%
                    $where1 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.account_commission_type', '=', 0],
                    ];
                    //固定金额
                    $where2 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.account_commission_type', '=', 1],
                    ];
                    //每月提成
                    $where3 = [
                        ['a.start_time', '<=', $currTime],
                        ['a.end_time', '>=', $currTime],
                        ['a.package_id', 'in', $package_ids],
                        ['a.account_commission_type', '=', 2],
                    ];
                } else {
                    $package_ids = (new Package())->where(['wq_user_id' => $user->store_user_id, 'status' => 2, 'is_delete' => 0])->column('package_id');
                    //收款金额*%
                    $where1 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.outworker_commission_type', '=', 0],
                    ];
                    //固定金额
                    $where2 = [
                        ['a.create_time', 'between', [strtotime($firstDay), $lastDay]],
                        ['a.package_id', 'in', $package_ids],
                        ['a.outworker_commission_type', '=', 1],
                    ];
                    //每月提成
                    $where3 = [
                        ['a.start_time', '<=', $currTime],
                        ['a.end_time', '>=', $currTime],
                        ['a.package_id', 'in', $package_ids],
                        ['a.outworker_commission_type', '=', 2],
                    ];
                }
                $filter = [
                    ['a.is_delete', '=', 0],
                    ['c.customer_type', '=', 1],
                    ['b.status', '=', 2],
                ];
                $query = $this
                    ->field('a.*,c.customer_identity')->alias('a')
                    ->with(['customer', 'package' => function ($qrery) {
                        $qrery->with(['store_user', 'kj_user', 'wq_user']);
                    }])
                    ->join('customer_package b', 'a.package_id=b.package_id')
                    ->join('customer c', 'a.customer_id=c.customer_id')
                    ->where($filter)
                    ->where(function ($query) use ($where1, $where2, $where3) {
                        $query->whereOr(function ($query) use ($where1) {
                            $query->where($where1);
                        })->whereOr(function ($query) use ($where2) {
                            $query->where($where2);
                        })->whereOr(function ($query) use ($where3) {
                            $query->where($where3);
                        });
                    })
                    ->order(['a.create_time' => 'desc']);
                if (!empty($param['export']) && $param['export'] == 1) {
                    $columns = [
                        '客户姓名',
                        '身份证号',
                        '公司名称',
                        '授权签约人',
                        '手机号码',
                        '服务名称',
                        '服务期限',
                        '开始日期',
                        '结束日期',
                        '录入时间',
                        '提成结算方式',
                        '成本金额',
                        '成交金额',
                        '提成金额',
                    ];
                    $datas = [];
                    $list = $query->select();
                    foreach ($list as $item) {
                        if ($user->position == 0) {
                            $arr = ['(成交价格-成本价格)*%', '固定金额', '每月提成'];
                            $commission_type = $arr[$item->sales_commission_type] ?? '';
                        } elseif ($user->position == 1) {
                            $arr = ['收款金额*()%', '固定金额', '每月提成'];
                            $commission_type = $arr[$item->account_commission_type] ?? '';
                        } else {
                            $arr = ['收款金额*()%', '固定金额', '每月提成'];
                            $commission_type = $arr[$item->outworker_commission_type] ?? '';
                        }

                        $datas[] = [
                            $item->customer ? ($item->customer->full_name ?: '-') : '-',
                            $item->customer ? ($item->customer->idnumber ?: '-') : '-',
                            $item->customer ? ($item->customer->corporate_name ?: '-') : '-',
                            $item->customer ? ($item->customer->signatory ?: '-') : '-',
                            $item->customer ? ($item->customer->mobile ?: '-') : '-',

                            $item->service_name,
                            $item->month ? $item->month . '个月' : '一次性服务',
                            $item->start_time_text ?: '-',
                            $item->end_time_text ?: '-',
                            $item->create_time ?: '-',
                            $commission_type ?: '-',

                            $item->cost_price ?: '-',
                            $item->collection_price ?: '-',
                            $user->position == 0 ? $item->sales_commission : ($user->position == 1 ? $item->account_commission : $item->outworker_commission),
                        ];
                    }
                    return base_url() . $this->outputExcel($columns, $datas);
                } else {
                    return $query->paginate(15);
                }
            } else {
                return [];
            }
        }

        if ($store['user']['is_super'] != 1) {
            $filter[] = ['b.store_user_id', '=', $store['user']['store_user_id']];
        }

        // 查询列表数据
        $list = $this->field('a.*,c.customer_identity')->where($filter)->alias('a')
            ->with(['customer', 'package' => function ($qrery) {
                $qrery->with(['store_user', 'kj_user', 'wq_user']);
            }])
            ->join('customer_package b', 'a.package_id=b.package_id')
            ->join('customer c', 'a.customer_id=c.customer_id')
            ->order(['a.create_time' => 'desc'])
            ->paginate(15);
        $standard_price = $this->alias('a')
            ->where($filter)
            ->join('customer_package b', 'a.package_id=b.package_id')
            ->join('customer c', 'a.customer_id=c.customer_id')
            ->sum('standard_price');

        $deal_price = $this->alias('a')
            ->where($filter)
            ->join('customer_package b', 'a.package_id=b.package_id')
            ->join('customer c', 'a.customer_id=c.customer_id')
            ->sum('deal_price');
        $collection_price = $this->alias('a')
            ->where($filter)
            ->join('customer_package b', 'a.package_id=b.package_id')
            ->join('customer c', 'a.customer_id=c.customer_id')
            ->sum('collection_price');
        $balance_price = $this->alias('a')
            ->where($filter)
            ->join('customer_package b', 'a.package_id=b.package_id')
            ->join('customer c', 'a.customer_id=c.customer_id')
            ->sum('balance_price');
        return [
            'list' => $list,
            'standard_price' => $standard_price,
            'deal_price' => $deal_price,
            'collection_price' => $collection_price,
            'balance_price' => $balance_price,
        ];
    }

    public function saveList($customer_id, $package_id, $data = [])
    {
        $customer = (new Customer)->details((int)$customer_id);
        if (!$customer) {
            $this->error = '客户信息不存在';
            return false;
        }
        $serviceData = [];
        foreach ($data as $item) {
            $service = (new \app\store\model\Service())->details($item['service_id']);
            if (!$service) {
                continue;
            }
            $types = [
                'gth', 'xgmnsr', 'ybnsr'
            ];

            $orporate_type = $customer->corporate_type;

            //成本
            $cost_type = $service[$types[$orporate_type] . '_cost_type'];
            $cost_value = $service[$types[$orporate_type] . '_cost_value'];
            if ($cost_type == 0) {
                $cost_value = $item['collection_price'] * $this->getPercentage($cost_value);
            } else if ($cost_type == 1) {
//                        $cost_value = $cost_value;
            } else if ($cost_type == 2) {
//                $cost_value = json_decode($cost_value, true);
//                $cost_value = (new Expenses())->where('id', 'in', $cost_value)->sum('price');
            }

            // 会计
            $account_commission_type = $service[$types[$orporate_type] . '_commission_account_type'];
            $commission_account = $service[$types[$orporate_type] . '_commission_account'];
            $account_commission = 0;
            if ($account_commission_type == 0) {
                $account_commission = $item['collection_price'] * $this->getPercentage($commission_account);
            } else {
                $account_commission = $commission_account;
            }

            // 销售
            $sales_commission_type = $service[$types[$orporate_type] . '_commission_sales_type'];
            $commission_sales = $service[$types[$orporate_type] . '_commission_sales'];
            $sales_commission = 0;
            if ($sales_commission_type == 0) {
                $sales_commission = ($item['collection_price'] - $cost_value) * $this->getPercentage($commission_sales);
            } else {
                $sales_commission = $commission_account;
            }

            //外勤
            $outworker_commission_type = $service[$types[$orporate_type] . '_commission_outworker_type'];
            $commission_outworker = $service[$types[$orporate_type] . '_commission_outworker'];
            $outworker_commission = 0;
            if ($outworker_commission_type == 0) {
                $outworker_commission = $item['collection_price'] * $this->getPercentage($commission_outworker);
            } else {
                $outworker_commission = $commission_outworker;
            }

            $serviceData[] = [
                'package_id' => $package_id,
                'customer_id' => $customer_id,
                'service_id' => $service->service_id,
                'service_name' => $service->service_name,
                'ledger_expenses' => $service->ledger_expenses,
                'corporate_type' => $customer->corporate_type,
                'standard_price' => $item['standard_price'],
                'deal_price' => $item['deal_price'],
                'collection_price' => $item['collection_price'],
                'balance_price' => $item['balance_price'],

                //成本价格
                'cost_type' => $cost_type,
                'cost_price' => $cost_value,

                //提成计算
                'account_commission_type' => $account_commission_type,
                'account_commission' => $account_commission,
                'sales_commission_type' => $sales_commission_type,
                'sales_commission' => $sales_commission,
                'outworker_commission_type' => $outworker_commission_type,
                'outworker_commission' => $outworker_commission,

                //服务期限
                'month' => $item['month'],

                'store_id' => self::$storeId,
                'create_time' => time(),
            ];
        }
        return $this->insertAll($serviceData);
    }

    public function getPercentage($value = 0)
    {
        $value = (int)$value > 100 ? 100 : (int)$value;
        return $value / 100;
    }

    /**
     * 更新记录
     * @param array $data
     * @return bool
     */
    public function edits(array $data): bool
    {
        if (!empty($data['start_time'])) {
            $data['start_time'] = strtotime($data['start_time']);
        }

        if (!empty($data['end_time'])) {
            $firstday = date("Y-m-d", strtotime($data['end_time']));
            $data['end_time'] = strtotime("$firstday +1 month -1 day");
        }

        if (!empty($data['create_time'])) {
            $data['create_time'] = strtotime($data['create_time']);
        }

        return $this->save($data) !== false;
    }


    private function getExportPath(): string
    {
        $filePath = 'downloads/' . getStoreId() . '/';
        !is_dir($filePath) && mkdir($filePath, 0755, true);
        return $filePath;
    }

    private function outputExcel(array $columns, array $excelList): string
    {
        // 生成工作表
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet()->setTitle('导出结果');
        // 列宽
        $sheet->getDefaultColumnDimension()->setWidth(30);
        // 默认行高
//        $sheet->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet->getStyle('1')->getFont()->setBold(true)->setName('微软雅黑 Light')->setSize(12);
        $sheet->getStyle('1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // A1单元格水平居中
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($excelList as $key => $item) {
            $row = $key + 2;
            //最后的合计行加粗
//            if (($key + 1) == count($excelList)) {
//                $sheet->getStyle($row)->getFont()->setBold(true)->setName('微软雅黑 Light')->setSize(12);
//            } else {
            // 设置单元格样式，使其支持换行

            $sheet->getStyle($row)->getFont()->setName('微软雅黑 Light')->setSize(11);
//            }
            $sheet->getStyle($row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // A1单元格水平居中
            foreach ($item as $k => $val) {
                $sheet->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }
        // 生成文件路径
        $fileName = '提成明细' . date('Ymd') . time() . '.xlsx';
        $filePath = $this->getExportPath();
        // 保存到文件
        try {
            $writer = new Xlsx($spreadsheet);
            $writer->save(public_path() . $filePath . $fileName);
        } catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
            throwError($e->getMessage());
        }
        return $filePath . $fileName;
    }


}
